﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using InformationExtraction.Common;
using InformationExtraction.Interface;

namespace InformationExtraction.Utils
{
    //cfj
    class SubmissionDateExtracter : IFeatureExtractable
    {
        #region IFeatureExtractable 成员

        List<int> IFeatureExtractable.Extract(Token token)
        {
            //if (token.Type == InformationType.SubmissionDate)
              //  Console.WriteLine("======================================== "+token.Content);
            List<int> fList = new List<int>();
            string word = token.Content;
            string line = token.InLine.Content;
            //fList.Add(GetSubmissionSpecified(line));
            
            //int f1 = GetMonth(word);
            //int f2 = GetDay(word);
            //int f3 = GetYear(word);
            //fList.Add(f1);
            //fList.Add(f2);
            //fList.Add(f3);
            //fList.Add(GetStandardFormat(word));
            // fList.Add(GetKeyValue(line));
          
            fList.Add(GetMonth(word));            
            fList.Add(GetDay(word));
            fList.Add(GetYear(word));
            fList.Add(GetDateFormat(token));            
            fList.Add(GetSubmissionSpecified(line));
            fList.Add(GetNotNotificationSpecified(line));
            fList.Add(GetNotCameraSpecified(line));
            //fList.Add(GetKeyValue(token));            
            //fList.Add(GetImportantNearBy(token));
           // fList.Add(GetMonthNearBy(line));
           // int f4 = GetKeyValue(line);
           // int f5 = GetKeyValue(token);
           // fList.Add(f4);
           // fList.Add(f5);
            //fList.Add((f1 + f2 + f3) > -3 ? 1 : -1);  
           // fList.Add(f4 + f5 == 2 ? 1 : -1);
           // fList.Add(GetMixed(token));
            return fList;
        }

        InformationType IFeatureExtractable.GetTargetType()
        {
            return InformationType.SubmissionDate;
            //throw new NotImplementedException();
        }


        #endregion
        #region private functions
        /// <summary>
        /// 提取第一个特征值
        /// 方法：是否是十二个月中的任何一个
        /// </summary>
        /// <param name="text"></param>
        /// <returns>是返回1，不是返回-1</returns>
        private int GetMonth(string word)
        {
            Regex r = new Regex(@"(^|\W)((January)|(February)|(March)|(April)|(May)|(June)|(July)|(August)|(September)|(October)|(November)|(December)|(Jan)|(Feb)|(Mar)|(Apr)|(May)|(Jun)|(Jul)|(Aug)|(Sep)|(Oct)|(Nov)|(Dec))($|\W)", RegexOptions.IgnoreCase);
            if (r.IsMatch(word))
            {
             //   Console.WriteLine(word);
                return 1;
            }

            return -1;
        }

        /// <summary>        
        /// 方法：是否使介于1-31之间的数字
        /// </summary>
        /// <param name="word"></param>
        /// <returns>是返回1，不是返回-1</returns>
        private int GetDay(string word)
        {
            Regex r = new Regex(@"^(0?\d|[12]\d|3[01])(st)?(rd)?(nd)?(th)?(,)?$");
            if (r.IsMatch(word))
            {
            //    Console.WriteLine(word);
                return 1;
            }

            else
                return -1;
        }

        /// <summary>
        /// 提取第四个特征值
        /// 方法：是否是介于1900-2099间的年份
        /// </summary>
        /// <param name="word"></param>
        /// <returns>是返回1，不是返回-1</returns>
        private int GetYear(string word)
        {
            Regex r = new Regex(@"^\W*(19|20)\d{2}\W*$");
            if (r.IsMatch(word))
            {
            //    Console.WriteLine(word);
                return 1;
            }

            else
                return -1;
        }

        // 是否有其Submissionc ttributes的明显字样
        private int GetSubmissionSpecified(string line)
        {
            Regex r = new Regex(@"(submission)|(submit)|(due)|(paper)|(deadline)|(accept)", RegexOptions.IgnoreCase);
            
             //   Regex r = new Regex(@"(submission)|(deadline)|(accept)", RegexOptions.IgnoreCase);
            if (r.IsMatch(line))
            {
              //  Console.WriteLine(line);
                return 1;
            }
            return -1;
        }

        // 是否有其camera ttributes的明显字样
        private int GetNotCameraSpecified(string line)
        {
            Regex r = new Regex(@"(camera)|(revised)", RegexOptions.IgnoreCase);

            //   Regex r = new Regex(@"(submission)|(deadline)|(accept)", RegexOptions.IgnoreCase);
            if (r.IsMatch(line))
            {
                //  Console.WriteLine(line);
                return -1;
            }
            return 1;
        }
        // 是否有Notification Attributes的明显字样
        private int GetNotNotificationSpecified(string line)
        {
            Regex r = new Regex(@"(notification)|(notified)|(author)|(letter)", RegexOptions.IgnoreCase);
            if (r.IsMatch(line))
                return -1;
            return 1;
        }

        //所在行是否有Month
        private int GetMonthNearBy(string line)
        {
            Regex r = new Regex(@"(January)|(February)|(March)|(April)|(May)|(June)|(July)|(August)|(September)|(October)|(November)|(December)|(Jan)|(Feb)|(Mar)|(Apr)|(May)|(Jun)|(Jul)|(Aug)|(Sep)|(Oct)|(Nov)|(Dec)");
            if (r.IsMatch(line))
                return 1;
            else
                return -1;
        }
        //是否是标准格式的日期
        private int GetStandardFormat(string word)
        {
            DateTime date;
            if (DateTime.TryParse(word, out date))
                return 1;
            else
                return -1;
        }
        private int GetKeyValue(string line)
        {
            if (line != null && line.Contains(":"))
            {
                string[] ls = line.ToLower().Split(':');
                if (ls[0].Contains("submit"))
                    return 1;
                return -1;
            }
            return -1;
        }

        //是否 XXX:YYYY格式 且包含月份
        private int GetKeyValue(Token token)
        {
            string line = token.InLine.Content;
            if (line != null || line != "")
            {
                if (line.Contains(":") && GetMonthNearBy(line) > 0)
                {
                    string[] ls = line.Split(':');
                    if (ls.Length == 2)
                    {
                        if (GetSubmissionSpecified(ls[0]) == 1 && GetMonthNearBy(ls[1]) == 1)
                        {
                         //   Console.WriteLine(line);
                            return 1;
                        }
                        else if (GetSubmissionSpecified(ls[1]) == 1 && GetMonthNearBy(ls[0]) == 1)
                        {
                        //    Console.WriteLine(line);
                            return 1;
                        }
                        
                    }
                    else if (ls.Length == 1 && line.EndsWith(":"))
                    {
                        string nl = token.Next.InLine.Content;
                        if (GetSubmissionSpecified(nl) == 1 && GetMonthNearBy(line) == 1)
                        {
                        //    Console.WriteLine(line);
                            return 1;
                        }
                        
                        else if (GetSubmissionSpecified(line) == 1 && GetMonthNearBy(nl) == 1)
                        {
                        //    Console.WriteLine(line);
                            return 1;
                        }
                        
                    }
                    return -1;
                }
                return -1;
            }
            return -1;
        }
        private int GetDateFormat(Token token)
        {
            string s = token.Content;//&& GetDay(token.Next.Content) == 1)
            if (GetMonth(s) == 1  || (GetMonthNearBy(token.InLine.Content) == 1 && (GetDay(s) == 1 || GetYear(s) == 1)) || GetStandardFormat(s) == 1)
            {
             //   Console.WriteLine("DateFormat: " +s);
                return 1;
            }
            else
                return -1;
        }
        private int GetMixed(Token token)
        {
            if (GetDateFormat(token) ==1 && GetKeyValue(token) == 1)
                return 1;
            else return -1;
        }

        private int GetImportantNearBy(Token token)
        {
            for (int i = token.InLine.No; i>(token.InLine.No-3) && i>=0; i-- )
            {
                string line = token.InLine.InDocument.Lines[i].Content;
                if(line.ToLower().Contains("important dates"))
                {
                   // Console.WriteLine(line);
                    return 1;
                }
            }
            return -1;
        }

        # endregion

    }
}
